{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "91c6a7ef",
   "metadata": {},
   "source": [
    "# MongoDB\n",
    "\n",
    ">`MongoDB` is a source-available cross-platform document-oriented database program. Classified as a NoSQL database program, `MongoDB` uses `JSON`-like documents with optional schemas.\n",
    ">\n",
    ">`MongoDB` is developed by MongoDB Inc. and licensed under the Server Side Public License (SSPL). - [Wikipedia](https://en.wikipedia.org/wiki/MongoDB)\n",
    "\n",
    "This notebook goes over how to use the `MongoDBChatMessageHistory` class to store chat message history in a Mongodb database.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d6ed3c8-b70a-498c-bc9e-41b91797d3b7",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "The integration lives in the `langchain-mongodb` package, so we need to install that.\n",
    "\n",
    "```bash\n",
    "pip install -U --quiet langchain-mongodb\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09c33ad3-9ab1-48b5-bead-9a44f3d86eeb",
   "metadata": {},
   "source": [
    "It's also helpful (but not needed) to set up [LangSmith](https://smith.langchain.com/) for best-in-class observability"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0976204d-c681-4288-bfe5-a550e0340f35",
   "metadata": {},
   "outputs": [],
   "source": [
    "# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71a0a5aa-8f12-462a-bcd0-c611d76566f8",
   "metadata": {},
   "source": [
    "## Usage\n",
    "\n",
    "To use the storage you need to provide only 2 things:\n",
    "\n",
    "1. Session Id - a unique identifier of the session, like user name, email, chat id etc.\n",
    "2. Connection string - a string that specifies the database connection. It will be passed to MongoDB create_engine function.\n",
    "\n",
    "If you want to customize where the chat histories go, you can also pass:\n",
    "1. *database_name* - name of the database to use\n",
    "1. *collection_name* - collection to use within that database"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0179847d-76b6-43bc-b15c-7fecfcb27ac7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-08-28T10:04:38.077748Z",
     "start_time": "2023-08-28T10:04:36.105894Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory\n",
    "\n",
    "chat_message_history = MongoDBChatMessageHistory(\n",
    "    session_id=\"test_session\",\n",
    "    connection_string=\"mongodb://mongo_user:password123@mongo:27017\",\n",
    "    database_name=\"my_db\",\n",
    "    collection_name=\"chat_histories\",\n",
    ")\n",
    "\n",
    "chat_message_history.add_user_message(\"Hello\")\n",
    "chat_message_history.add_ai_message(\"Hi\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6e7b8653-a8d2-49a7-97ba-4296f7e717e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[HumanMessage(content='Hello'), AIMessage(content='Hi')]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat_message_history.messages"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e352d786-0811-48ec-832a-9f1c0b70690e",
   "metadata": {},
   "source": [
    "## Chaining\n",
    "\n",
    "We can easily combine this message history class with [LCEL Runnables](/docs/how_to/message_history)\n",
    "\n",
    "To do this we will want to use OpenAI, so we need to install that.  You will also need to set the OPENAI_API_KEY environment variable to your OpenAI key.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6558418b-0ece-4d01-9661-56d562d78f7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "from langchain_core.runnables.history import RunnableWithMessageHistory\n",
    "from langchain_openai import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "86ddfd3f-e8cf-477a-a7fd-91be3b8aa928",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "assert os.environ[\n",
    "    \"OPENAI_API_KEY\"\n",
    "], \"Set the OPENAI_API_KEY environment variable with your OpenAI API key.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "82149122-61d3-490d-9bdb-bb98606e8ba1",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\"system\", \"You are a helpful assistant.\"),\n",
    "        MessagesPlaceholder(variable_name=\"history\"),\n",
    "        (\"human\", \"{question}\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "chain = prompt | ChatOpenAI()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "2df90853-b67c-490f-b7f8-b69d69270b9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "chain_with_history = RunnableWithMessageHistory(\n",
    "    chain,\n",
    "    lambda session_id: MongoDBChatMessageHistory(\n",
    "        session_id=session_id,\n",
    "        connection_string=\"mongodb://mongo_user:password123@mongo:27017\",\n",
    "        database_name=\"my_db\",\n",
    "        collection_name=\"chat_histories\",\n",
    "    ),\n",
    "    input_messages_key=\"question\",\n",
    "    history_messages_key=\"history\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0ce596b8-3b78-48fd-9f92-46dccbbfd58b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is where we configure the session id\n",
    "config = {\"configurable\": {\"session_id\": \"<SESSION_ID>\"}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "38e1423b-ba86-4496-9151-25932fab1a8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='Hi Bob! How can I assist you today?')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "2ee4ee62-a216-4fb1-bf33-57476a84cf16",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='Your name is Bob. Is there anything else I can help you with, Bob?')"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
